﻿using JustMetClient.Commons;
using JustMetClient.Socket.Models;
using JustMetClient.Tools;
using Azylee.Core.ThreadUtils.SleepUtils;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace JustMetClient.Modules.SocketModule
{
    public static class SocketSendQueue
    {
        private static ConcurrentQueue<MessageModel> Queue = new ConcurrentQueue<MessageModel>();
        public static void Start()
        {
            StartSendQueue();
        }
        public static void Add(MessageType type, string[] values, int retry = 0)
        {
            try
            {
                if (Queue.Any(x => x.Type == type && string.Join(",", x.Values) == string.Join(",", values)))
                {
                    R.Log.v($"SocketSendQueue:[{Queue.Count}]:Add:IsExist:" + type.ToString() + string.Join(",", values));
                }
                else
                {
                    Queue.Enqueue(new MessageModel()
                    {
                        Type = type,
                        Account = R.Account,
                        Mac = R.NetInfo.Mac,
                        Values = values,
                        Retry = retry
                    });
                    R.Log.v($"SocketSendQueue:[{Queue.Count}]:Add:OK:" + type.ToString() + string.Join(",", values));
                }
            }
            catch { R.Log.v($"SocketSendQueue:[{Queue.Count}]:Add:Error"); }
        }
        private static void StartSendQueue()
        {
            //启动任务
            Task.Factory.StartNew(() =>
            {
                //设置退出条件
                while (!R.Socket.ConnectCancelToken.IsCancellationRequested)
                {
                    //如果通信正常，并且队列中存在元素
                    if (R.Socket.IsConnect && Queue.Any())
                    {
                        //循环进行操作
                        for (int i = 0; i < Queue.Count; i++)
                        {
                            try
                            {
                                MessageModel model = null;
                                if (Queue.TryDequeue(out model))
                                {
                                    //更新账号和mac地址信息（防止因连接问题导致的信息不正确，发送脏数据）
                                    model.Account = R.Account;
                                    model.Mac = R.NetInfo.Mac;
                                    //读取成功后，发送相关指令
                                    bool flag = R.Socket.Current.SendMessage(model);
                                    if (flag)
                                    {
                                        R.Socket.LastSendTime = DateTime.Now;//记录最后一次发送成功时间
                                        R.Log.v(string.Format("socket send ok : {0} : {1}", model.Type.ToString(), model.Content));
                                    }
                                    else
                                    {
                                        if (model.Retry > 0)
                                        {
                                            //发送指令失败，并且设置了retry重试，则重新添加到队列中
                                            Add(model.Type, model.Values, model.Retry - 1);
                                        }

                                        R.Log.v(string.Format("socket send error : {0} : {1}", model.Type.ToString(), model.Content));
                                        //通信失败，延迟等待，跳出当前循环操作
                                        Sleep.S(R.TimeInterval.SocketQueueError);
                                        break;
                                    }
                                }
                            }
                            catch { }
                        }
                    }
                    Sleep.S(R.TimeInterval.SocketQueue);
                }
            });
        }
    }
}
